package com.dxg.provider.filter;

import com.dxg.provider.token.SmsAuthenticationToken;
import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

/**
 * @author dingxigui
 * @version 1.0
 * @date 2021/7/30 15:57
 */

public class SmsAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {

  // ~ Static fields/initializers
  // =====================================================================================

  private String usernameParameter = "username";
  private String passwordParameter = "password";
  private boolean postOnly = true;

  // ~ Constructors
  // ===================================================================================================

  public SmsAuthenticationProcessingFilter() {
    super(new AntPathRequestMatcher("/sms/login", "POST"));
  }

  // ~ Methods
  // ========================================================================================================

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request,
      HttpServletResponse response) throws AuthenticationException {
    if (postOnly && !request.getMethod().equals("POST")) {
      throw new AuthenticationServiceException(
          "Authentication method not supported: " + request.getMethod());
    }

    String username = obtainUsername(request);
    String password = obtainPassword(request);

    if (username == null) {
      username = "";
    }

    if (password == null) {
      password = "";
    }

    username = username.trim();

    SmsAuthenticationToken authRequest = new SmsAuthenticationToken(
        username, password);

    // 允许子类设置details 属性
    setDetails(request, authRequest);

    return this.getAuthenticationManager().authenticate(authRequest);
  }

  /**
   * 获取用户名
   * @param request
   * @return
   */
  protected String obtainPassword(HttpServletRequest request) {
    return request.getParameter(passwordParameter);
  }

  protected String obtainUsername(HttpServletRequest request) {
    return request.getParameter(usernameParameter);
  }


  protected void setDetails(HttpServletRequest request,
      SmsAuthenticationToken authRequest) {
    authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
  }


  public void setUsernameParameter(String usernameParameter) {
    Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
    this.usernameParameter = usernameParameter;
  }


  public void setPasswordParameter(String passwordParameter) {
    Assert.hasText(passwordParameter, "密码参数不能为空");
    this.passwordParameter = passwordParameter;
  }

  /**
   * 是否仅允许post请求
   * @param postOnly
   */
  public void setPostOnly(boolean postOnly) {
    this.postOnly = postOnly;
  }

  public final String getUsernameParameter() {
    return usernameParameter;
  }

  public final String getPasswordParameter() {
    return passwordParameter;
  }
}
